// const vm =  new KVue({
//     data: {
//         name: 'kkk',
//         age: 18,
//         obj: {
//             phone:1361111111,
//         }
//     },
//     created() {
        
//     }
// })
class KVue {
    constructor(options) {
        this.$data = options.data;
        this.observe(this.$data)
        // 数据初始化完成时执行 created
        if(options.created) {
            options.created.call(this)
        }

        // 执行编译
        new Compile(options.el, this.$data)

        // 下面是伪码 用来测试的代码
        // 当页面里出现 {{name}} 的时候 需要生成一个watcher
        // new Watcher(this.$data, 'name', () => {
        //     // 响应式更新视图
        //     // 当name发生改变时的回调 
        //     // 要通过这个回调来更新视图
        //     console.log('name修改了 快去更新视图')
        // })
        // this.$data.name = '123'
    }
    observe(data) {
        if(!data || typeof data !== 'object') return;

        Object.keys(data).forEach(key => {
            this.defineReactive(data, key, data[key])
            this.proxyData(key)
        })
    }
    // 响应式函数
    defineReactive(data,key,value) {
        const dep = new Dep();
        // 递归
        this.observe(value)
        Object.defineProperty(data, key, {
            get() {
                console.log(`${key}被读取了`)
                Dep.target && dep.addWatcher(Dep.target)
                return value;
            },
            set(newVal) {
                if(newVal === value) return;
                value = newVal;
                console.log(`${key}被修改了`)
                dep.notify(); // 通知所有watcher更新
            }
        })
    }
    proxyData(key) {
        Object.defineProperty(this, key, {
            get() {
                return this.$data[key];
            },
            set(newVal) {
                this.$data[key] = newVal;
            }
        })
    }
}

// 管理若干Watcher实例，它和data中的属性1:1关系
class Dep {
    constructor() {
        this.Watchers = [];
    }
    addWatcher(watcher) {
        this.Watchers.push(watcher)
    }
    notify() {
        console.log(this.Watchers)
        // 通知所有的watcher进行更新
        this.Watchers.forEach(watcher => {
            console.log(1)
            watcher.update()
        })
    }
}

// 监听器: 负责更新页面中的具体绑定
class Watcher {
    constructor(vm,key,callback) {
        this.vm = vm;
        this.key = key,
        this.callback = callback;

        Dep.target = this;
        this.vm[this.key]; // 触发读取操作
        Dep.target = null;
    }
    update() {
        this.callback()
    }
}